import re

from django.db import models
from django.utils import timezone
from django.core import validators
from django.utils.translation import ugettext_lazy as _
from django.contrib.auth.models import AbstractUser

from .services import get_default_uuid
from .services import get_user_file_path
from .services import get_message_attachement_path


class PermissionsMixin(models.Model):
    """
    A mixin class that adds the fields and methods necessary to support
    Django"s Permission model using the ModelBackend.
    """
    "超级管理员"
    is_superuser = models.BooleanField(_("superuser status"), default=False,
                                       help_text=_("Designates that this user has all permissions without "
                                                   "explicitly assigning them."))

    class Meta:
        "子类继承，不生成数据表"
        abstract = True

    def has_perm(self, perm, obj=None):
        """
        Returns True if the user is superadmin and is active
        """
        return self.is_active and self.is_superuser

    def has_perms(self, perm_list, obj=None):
        """
        Returns True if the user is superadmin and is active
        """
        return self.is_active and self.is_superuser

    def has_module_perms(self, app_label):
        """
        Returns True if the user is superadmin and is active
        """
        return self.is_active and self.is_superuser

    @property
    def is_staff(self):
        return self.is_superuser


class User(AbstractUser, PermissionsMixin):
    """
    用户表
    """
    uuid = models.CharField(max_length=32, editable=False, null=False,
                            blank=False, unique=True, default=get_default_uuid)

    "用户名"
    username = models.CharField(_("username"), max_length=255, unique=True,
                                help_text=_("Required. 30 characters or fewer. Letters, numbers and "
                                            "/./-/_ characters"),
                                validators=[
                                    validators.RegexValidator(re.compile("^[\w.-]+$"), _("Enter a valid username."),
                                                              "invalid")
                                ])
    "活跃用户"
    is_active = models.BooleanField(_("active"), default=True,
                                    help_text=_("Designates whether this user should be treated as "
                                                "active. Unselect this instead of deleting accounts."))
    "系统用户"
    is_system = models.BooleanField(null=False, blank=False, default=False)
    "邮件"
    email = models.EmailField(_("email address"), max_length=255, blank=True, unique=True)
    "全名"
    full_name = models.CharField(_("full name"), max_length=256, blank=True)
    "简介"
    bio = models.TextField(null=False, blank=True, default="", verbose_name=_("biography"))
    "照片"
    photo = models.FileField(upload_to=get_user_file_path,
                             max_length=500, null=True, blank=True,
                             verbose_name=_("photo"))
    "token"
    token = models.CharField(max_length=200, null=True, blank=True, default=None,
                             verbose_name=_("token"))
    "加入日期"
    date_joined = models.DateTimeField(_("date joined"), default=timezone.now)
    "接受条款"
    accepted_terms = models.BooleanField(_("accepted terms"), default=True)
    "阅读条款"
    read_new_terms = models.BooleanField(_("new terms read"), default=False)
    "默认语言"
    lang = models.CharField(max_length=20, null=True, blank=True, default="en",
                            verbose_name=_("default language"))
    "默认主题"
    theme = models.CharField(max_length=100, null=True, blank=True, default="theme",
                             verbose_name=_("default theme"))

    _cached_memberships = None

    USERNAME_FIELD = "username"

    class Meta:
        verbose_name = "user"
        verbose_name_plural = "users"
        ordering = ["username"]

    def __str__(self):
        return self.get_full_name()

    def get_short_name(self):
        "Returns the short name for the user."
        return self.username

    def get_full_name(self):
        return self.full_name or self.username or self.email

    def _fill_cached_memberships(self):
        self._cached_memberships = {}
        qs = self.memberships.select_related("user", "project", "role")
        for membership in qs.all():
            self._cached_memberships[membership.project.id] = membership

    @property
    def cached_memberships(self):
        if self._cached_memberships is None:
            self._fill_cached_memberships()

        return self._cached_memberships.values()

    def cached_membership_for_project(self, project):
        if self._cached_memberships is None:
            self._fill_cached_memberships()

        return self._cached_memberships.get(project.id, None)


class UserMessage(models.Model):
    """
    用户信息
    """
    "消息内容"
    message_content = models.TextField(blank=False, null=False, verbose_name=_("message content"))
    "消息标题"
    message_title = models.CharField(max_length=128, blank=True, null=True, verbose_name=_("message title"))
    "创建日期"
    created_date = models.DateTimeField(auto_now_add=True, verbose_name=_("created date"))
    "消息附件"
    attachment = models.FileField(upload_to=get_message_attachement_path, null=True, blank=True,
                                  verbose_name=_("message attachment"))
    "发送方"
    send_user = models.ForeignKey(User, blank=False, null=True, on_delete=models.CASCADE, related_name="send_user",
                                  verbose_name="消息发送方")
    "接收方"
    accept_user = models.ForeignKey(User, blank=False, null=True, on_delete=models.CASCADE,
                                    related_name="accept_user", verbose_name="消息接收方")
    "消息状态"
    message_statue = models.BooleanField(default=True, null=False, blank=True, verbose_name="信息状态")

    class Meta:
        verbose_name = "用户消息"
        verbose_name_plural = "用户消息"
